using System;
using System.Collections;
using Sedna.Core.Controls.Support.Javascript;
using Spring.Util;

namespace Sedna.Core.Controls.Support
{
	/// <summary>
	/// Utility class for Javascript generatoration.
	/// </summary>
	public class JavascriptUtil
	{
		private JavascriptUtil()
		{
			//Utility class
		}

		public static string VariableDeclaration(string name, string value)
		{
			return String.Format("var {0}={1};", name, value);	
		}
	    
	    public static string GetElementById(string id)
	    {
            return String.Format("document.getElementById(\"{0}\")", id);
	    }
	    
	    public static string ObjectReferenceByNode(string nodeId)
	    {
            return String.Format("Framework.instance.getControlByName(\"{0}\")", nodeId);
        }

	    public static string ObjectDeclarationByNode(string objectName, string nodeId)
	    {
            return String.Format("var {0}=Framework.instance.getControlByName(\"{1}\");", objectName, nodeId);	    
	    }
	    
		public static string ObjectDeclaration(string objectName, string className, bool encloseWithQuotes, params object[] parameters)
		{
			string serializedParameters = SerializeParameters(encloseWithQuotes, parameters);
		    string declaration=String.Format("new {0}({1})", className, serializedParameters);	
			if (objectName==null||String.Empty.Equals(objectName))
			{
				return declaration;
			}
			return String.Format("var {0}={1};", objectName, declaration);		
		}

	    private static string SerializeParameters(bool encloseWithQuotes, object[] parameters)
	    {
	        string serializedParameters;
	        if (encloseWithQuotes)
	        {
	            serializedParameters=Serialize(EncloseWithQuotes(parameters));
	        }
	        else
	        {
	            serializedParameters=Serialize(parameters);
	        }
	        return serializedParameters;
	    }

	    public static string ArrayDeclaration(string arrayName, bool encloseWithQuotes, params object[] parameters)
	    {
            string serializedParameters = SerializeParameters(encloseWithQuotes, parameters);
            string declaration = String.Format("[{0}]", serializedParameters);
            if (arrayName == null || String.Empty.Equals(arrayName))
            {
                return declaration;
            }
            return String.Format("var {0}={1};", arrayName, declaration);
        }
	    
		public static string EncloseWithQuotes(object arguments)
		{
			return String.Format("\"{0}\"", JavascriptUtil.ToStringLiteral(arguments!=null?arguments.ToString():String.Empty));
		}

		public static ICollection EncloseWithQuotes(ICollection arguments)
		{
			IList enclosedArguments=new ArrayList(arguments.Count);
			foreach (object argument in arguments)
			{
				enclosedArguments.Add(EncloseWithQuotes(argument));
			}
			return enclosedArguments;	
		}

		public static string Serialize(ICollection arguments)
		{
			return Serialize(arguments, ",");
		}

		public static string Serialize(ICollection arguments, string delimiter)
		{
			string serialized=String.Empty;
		    if (arguments==null)
		    {
                return serialized;
		    }
			foreach (object arg in arguments)
			{
				serialized+=arg+delimiter;
			}
			if (serialized.Length>0)
			{
				serialized=serialized.Substring(0,serialized.Length-1);
			}
			return serialized;
		}

		public static string Serialize(IDictionary arguments, string pairsDelimiter, string keyValueDelimiter)
		{
			if (arguments==null)
			{
				return String.Empty;
			}
			string serialized=String.Empty;
			foreach (object key in arguments.Keys)
			{
				serialized+=(String.Empty.Equals(serialized.Trim())?"":pairsDelimiter)+key+keyValueDelimiter+arguments[key];
			}
			return serialized;
		}


		public static string ToScriptObject(object obj)
		{
			return new ScriptObjectGenerator(obj).ToScript();
		}
	    
	    /// <summary>
	    /// Replaces all special symbols with esacepe sequence
	    /// </summary>
	    public static string ToStringLiteral(string source)
	    {
            if (StringUtils.IsNullOrEmpty(source)) return source;
            string target = source;
            target = target.Replace("\\", "\\\\");
            target = target.Replace("\n", "\\n");
            target = target.Replace("\"", "\\\"");
            target = target.Replace("'", "\\'");
            return target;
	    }

	}

}
